/*lic*/
#ifndef __I2C_COMMUNICATION_MODULE_H__
#define __I2C_COMMUNICATION_MODULE_H__
#include "main.h"
#include "I2CInitHelper.h"
#include "RtcInitHelper.h"

#include <time.h>

// RTC 宏定义
#define RTC_CHECK_TIME_TYPE 0x02 // 0x01是秒对时， 0x02是小时对时， 0x03是日对时 0x04是自定义定时器对时。0x00是错误设置，其实也是不主动对时
#define RTC_CHECK_TIME 60 * 60 * 1000 
#define RTC_FLASH_DELAY 2 // RTC写入延迟秒数
// RTC地址
extern uint8_t rtc_addr;
// RTC状态控制
#define HAD_INNER_RTC 0x01
#define HAD_EXT_RTC 0x02
#define RTC_INITED 0x04
#define EXT_RTC_WRITABLE 0x08 // 是否已关闭写保护
#define EXT_RTC_32K_NVIC 0x10 // 是否打开32.768k
#define EXT_RTC_INIT_PRE_TIMER_NVIC 0x20 // 是否打开秒中断
#define EXT_RTC_STOPED 0x40 // RTC是否发生过停止
#define START_RTC_FLASH_TASK 0x80 // 是否已经开始刷新时间字符串

// RTC时序刷新控制
#define EXT_RTC_CHECK_TIME_OK 0x01 // RTC是否已经刷新完毕（如果需要刷新就把这个置0）
#define EXT_RTC_FLASH_INNER_RTC 0x02 // 需要从外部RTC刷新时间

// RTC刷新间隔类型
#define RTC_FLASH_NONE 0x00
#define RTC_FLASH_PRE_SEC 0x01
#define RTC_FLASH_PRE_MIN 0x02
#define RTC_FLASH_PRE_HOUR 0x03
#define RTC_FLASH_PRE_DAY 0x04

// RTC事件
// 发生外部RTC秒中断
#define EVENT_EXT_RTC_GET_SEC_INTC (1 << 0)
// 通知对时任务去对时去
#define EVENT_EXT_RTC_START_CHECK_TIME_TASK (1 << 1)
// 通知对时任务已经完成
#define EVENT_EXT_RTC_START_CHECK_TIME_TASK_FINISHED (1 << 2) // 这是一个保留项	，如果需要阻塞式更新时间，去解开对应的注释即可
// 发生外部RTC半秒中断
#define EVENT_EXT_RTC_GET_HALF_SEC_INTC (1 << 3)


// RTC任务控制结构体
typedef struct __Tag_Rtc_Ctrl_Task_Def {
	uint8_t rtc_status; // RTC状态指示
	
	// 绑定状态，确定i2c的运行状态
	//struct rt_messagequeue *i2c_mq;
	// 外部rtc控制对象
	I2c_Data_Task_Def i2c_ctrl_obj;
	uint8_t ext_rtc_status;
	uint8_t ext_rtc_flash_squence;
	uint8_t time_update_squence_type;
	uint8_t inner_rtc_flash_delay;
	// rtc事件
	struct rt_event rtc_ctrl_event;
	// 内部rtc资源锁
	//rt_mutex_t inner_rtc_busy;
	// 外部rtc资源锁
	//rt_mutex_t ext_rtc_busy;
} Rtc_Ctrl_Task_Def;

// 全局时间结构体
extern Time_Info_Def sys_time_info;
// rtc
extern Rtc_Ctrl_Task_Def rtc_ctrl_task;

// 初始化结构体
rt_err_t Init_Rtc_Task_Obj(Rtc_Ctrl_Task_Def* obj, CM_I2C_TypeDef *CM_I2Cx, char* i2c_name);

// 时间管理函数会分为两条线。一条高优先级负责更新时间字符串，低优先级负责同步内部RTC。内部RTC主要用来设闹钟的，不是为了算时间。
// 更新时间字符串的优先级为6，更新RTC的优先级为7
// 时间管理线程主函数
// 主要负责外部事件同步到RTC，以及外部RTC更新内部RTC
void Time_Manager_Thread(void *parmameter);
// 时间更新线程主函数
// 主要负责向外部RTC更新万年历，以及刷新时间字符串
void Flash_Time_Info_Thread(void *parmameter);

// RTC中断
void INT_SRC_RTC_I2C_RXI_IrqCallback(void);
void INT_SRC_RTC_I2C_TXI_IrqCallback(void);
void INT_SRC_RTC_I2C_TEI_IrqCallback(void);
void INT_SRC_RTC_I2C_EEI_IrqCallback(void);

/** \!brief RTC主要函数
*
*/
// 关闭写保护,当force_check为true时，跳过标志位强制检查是否已经打开。
rt_err_t Sd8804_Write_Enable(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// 打开写保护
rt_err_t Sd8804_Write_Disable(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// 设置RTC时间
rt_err_t Sd8804_Write_Data_Time(Rtc_Ctrl_Task_Def *i2c_ctrl_task, Time_Info_Def* time_obj);
// 读取RTC时间
rt_err_t Sd8804_Read_Data_Time(Rtc_Ctrl_Task_Def *i2c_ctrl_task, Time_Info_Def* time_obj);
// 开启32.768K频率输出
rt_err_t Sd8804_Start_32K(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// 关闭32.768K频率输出
rt_err_t Sd8804_Stop_32K(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// 初始化秒中断，当force_check为true时，跳过标志位强制检查是否已经打开。
rt_err_t Sd8804_Init_Sec_Intc(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// 关闭初始化秒中断
// 设置PPS滤波
rt_err_t Sd8804_Set_PPS_Error_Intc(Rtc_Ctrl_Task_Def *rtc_ctrl_task_obj);
rt_err_t Sd8804_Stop_Sec_Intc(Rtc_Ctrl_Task_Def *i2c_ctrl_task, bool force_check);
// RTC是否发生过关闭， 仅能判断每次上电状态。当RTC发生过重启会置位，任何写操作都会清零这个
rt_err_t Ext_Rtc_Stoped(Rtc_Ctrl_Task_Def *i2c_ctrl_task);
// RTC复位校准寄存器。确保每次都正确复位
rt_err_t Ext_Rtc_Reset_Tmp_Ttf(Rtc_Ctrl_Task_Def *rtc_ctrl_task_obj);
// RTC主要函数

// 整个RTC任务分为两个部分。一个是预初始化结构体。一个是启动任务
void Init_Time_Pre_Obj(void);

#endif /* __I2C_COMMUNICATION_MODULE_H__ */

/*eof*/
